from bs4 import BeautifulSoup
from selenium import webdriver
from selenium.common import NoSuchElementException
from selenium.webdriver.common.by import By
from bs4 import BeautifulSoup
from address import *
import time
import re
from webdriver_manager.microsoft import EdgeChromiumDriverManager
from selenium.webdriver.edge.service import Service
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.chrome.service import Service

# 点击问题窗中，点击element中包含的选项序号
def check_if_correct(element: list) -> bool:
    global browser
    for i in element:
        if i:
            browser.find_element(By.XPATH,
                                 f'//*[@id="playTopic-dialog"]/div/div[2]/div/div[1]/div/div/div[2]/ul/li[{i}]').click()
    soup = get_page_source()
    pre_is_correct = soup.find('p', class_="topic-title")
    is_correct = pre_is_correct.find('span').get_text(strip=True)

    if is_correct == '正确':  # 结果正确结束答题
        return True
    else: return False

    #获取问题窗口中有多少个选项
def get_options_range(soup) ->int|None:
    pre_question_range = soup.find('ul', class_="topic-list")
    question_range = 0
    if pre_question_range:
        li_tags = pre_question_range.find_all('li')
        print(f"一共{len(li_tags)}个选项")
        question_range = len(li_tags)
        return question_range

#问题窗口处理方法
def question_dispose()->None:
    soup_for_qd = get_page_source()
    question = soup_for_qd.find('span',class_="title-tit")
    if question:
        #输出是单选题或者多选题
        print(f"要做题了，题型是{question.get_text(strip=True)}")
        option_number = get_options_range(soup_for_qd)
        for mask in range(0,2**option_number):
            select = list()
            for i in range(option_number):
                if mask & (1<<i):
                    select.append(i)

                if check_if_correct(select):
                    print("找到正确答案了")
                    browser.find_element(By.XPATH, close_question_windows_Xpath).click()  # 点击关闭
                    video_continue()
                    break
                time.sleep(0.1)
        try:
            check_if_correct([1,2,3])
            browser.find_element(By.XPATH, close_question_windows_Xpath).click()
        except:
            pass


#获取将要学的课的名字
def get_class_name(soup) -> None:
    titles = soup.find(course_element,course_class_name)

    for title in titles:
        class_name= title.get_text(strip=True)
        class_name_list.append(class_name)
    class_counter = 1
    for name in class_name_list:
        print(f"{class_counter}:"+name)
        class_counter += 1
    browser.find_element(By.XPATH, class_Xpath ).click()

#获取这个视屏的进度并判断是否进入下一个视频
def video_period_and_next_episode(soup):
    currentTime = soup.find('span', class_="currentTime").get_text(strip=True)
    duration = soup.find('span', class_="duration").get_text(strip=True)
    print(f"正在刷课：{currentTime}::{duration}")
    if currentTime == duration:
        print("进入下一讲")  # 进入下一讲
        mouse_movement()  # 换起时间轴
        browser.find_element(By.ID, next_epoisode_id).click()# 点击下一讲
        time.sleep(1)
        video_continue()

    return currentTime


#点击屏幕中央，继续或暂停视频
def video_continue() -> None:
    print("视屏现在暂停|播放")
    global browser
    try:
        browser.find_element(By.XPATH, class_continue_Xpath).click()
    except NoSuchElementException:
        print("没法继续或者暂停")
    except:
        print("不清楚原因，反正不许这样点击")

#自动获取当前网站的代码，创建bs
def get_page_source():
    global browser
    datas = browser.page_source
    soup = BeautifulSoup(datas, 'html.parser')
    return soup

#获取selenium的自动化窗口
def get_browser():
    try:vir_browser = webdriver.Edge(service=Service(EdgeChromiumDriverManager().install()))
    except:vir_browser = webdriver.Chrome(service=Service(ChromeDriverManager().install()))
    vir_browser.get('https://www.zhihuishu.com/')
    return vir_browser

if __name__ == '__main__':
    print(
        "###1.1、修改了无法使用知到登录的bug\n"
        "###1.2、可以手动选课自动学习,只需要登录后直接打开相应视屏界面\n"
        "智慧树自动刷课程序，芽菜豆腐制作\n"
        "本程序只能刷智慧树的体育课，本人懒得暴露接口了，如果想刷别的课请找我\n"
        "本程序只能在Edge和chrome中运行，推荐Edge,毕竟本人是在Edge中测试的\n"
        "第一次启动会等待较长时间（配置浏览器自动挡驱动），待浏览器打开后请跟着指示一步一步操作，即完成后敲回车\n"
        "由于本程序涉及鼠标自动操作，请将课网页至于左半边屏幕，且刷课时最好不要操作电脑\n"
        "本程序五秒刷新一次，所以可能会有延迟，最好别动它，毕竟第一版，不是很稳定\n"
        "这个程序毕竟是机器遇到验证码就懵逼了"
          )

    browser = get_browser()
    #让用户登录完成按回车键
    a = input("请登录")
    try:
        browser.find_element(By.XPATH, my_class_address).click()
        a = input("待网站加载完成后请敲回车")
    except:
        pass
    soup = get_page_source()
    try:
        get_class_name(soup)
        a = input("请关闭弹出网页，后才能开始刷课")
    except:
        pass
    error_counter = 0;ct = 0;pre_current_time = 0.0
    while True:
        try:
            soup1 = get_page_source()
            currentTime = video_period_and_next_episode(soup1)
            question_dispose()
            if currentTime == pre_current_time or currentTime == 0.0:
                ct+=1
            else:
                ct = 0
                pre_current_time = currentTime
            if 1 <= ct < 5:
                video_continue()
            elif ct >= 5:
                print("播放受阻，已退出")
                break

        except Exception as e:
            print(f"ERROR {e}")
            error_counter += 1
            if error_counter == 10:
                break
        time.sleep(5)

